package org.jiamandan.com.strategy.impl.tram.cmd;

import com.alibaba.fastjson.JSON;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jiamandan.com.constant.BizConstant;
import org.jiamandan.com.dto.ZDChargeDto;
import org.jiamandan.com.entity.RechargeGun;
import org.jiamandan.com.service.IRechargeGunService;
import org.jiamandan.com.strategy.impl.tram.TramBasicService;
import org.jiamandan.com.utils.CommonUtil;
import org.jiamandan.com.utils.ZDObjectUtil;
import org.springframework.stereotype.Service;

/**
 * @version Revision 1.0.1
 * @版权：版权所有 (c) 2021
 * @author:Jmd

 * @see:
 * @创建日期：2022-11-28 11:09
 * @功能说明： 该报文是后台服务器远程下发启动充电命令，后台服务器在下发该报文之前应先查询确
 * 认对应充电枪的工作状态是空闲且已插枪的。报文中字段“帐户余额 accountBalance”为预
 * 充金额，不管充电桩是否为在线状态，当累计充电金额将达到该值时应主动停止充电。后台
 * 服务器下发此命令后，应等待充电桩启动充电，最长等待时间应超过 90 秒。
 * @begin
 * @修改记录:
 * @修改后版本 修改人        修改内容
 * @2022-11-28 11:09	         Jmd        	创建
 * @end
 */
@Slf4j
@AllArgsConstructor
@Service(value = BizConstant.CmdClass.CMD_101_SERVICE)
public class ZDIssueChargeService implements TramBasicService {

    private IRechargeGunService iRechargeGunService;

    @Override
    public void doExecute(byte[] data, Channel client) {
        ZDChargeDto dto = JSON.parseObject(CommonUtil.bytesToString(data), ZDChargeDto.class);
        RechargeGun gun = iRechargeGunService.getById(dto.getGunId());
        //如果充电枪的工作状态不是空闲且已插枪的
//        if (!BizConstant.LinkStatus.LINK.equals(gun.getLinkStatus()) ||
//                !BizConstant.WorkStatus.FREE.equals(gun.getWorkStatus())) {
//            log.error("充电枪不在线");
//            return;
//        }
        // 充电枪编号 + 充电类型 + 充电模式 + 限制值 + 预约时间 + 屏幕操作停机码 + 帐户余额 + 平台订单类型 + 充电流水号
        // 5.1. CMD=101 下发启动充电
        StringBuilder payload = new StringBuilder();
        //充电枪编号
        payload.append(StringUtils.leftPad(CommonUtil.toHexString(gun.getGunNo()), 2, '0'));
        // 充电类型 0：立即充电    1：预约充电
        payload.append(StringUtils.leftPad(Integer.toHexString(0), 2, '0'));
        // 0：自动充满  1：按时间充电 2：按金额充电 3：按电量充电 4：按 SOC 充电
        payload.append(StringUtils.leftPad(Integer.toHexString(2), 2, '0'));
        //充电模式=0：填 0；
        //充电模式=1：单位分钟；
        //充电模式=2：单位元，精确到小数点后两位；
        // 充电模式=3：单位度，精确到小数点后三位；
        //充电模式=4：单位%，限制本次充电 SOC
        payload.append(StringUtils.rightPad(Integer.toHexString(10000), 8, '0'));
        //预约时间
        payload.append(StringUtils.rightPad(Integer.toHexString(0), 8, '0'));
        //屏幕操作停机码
        payload.append(StringUtils.rightPad(Integer.toHexString(0), 4, '0'));
        //帐户余额
        payload.append(StringUtils.rightPad(Integer.toHexString(1000), 8, '0'));
        //平台订单类型
        payload.append(StringUtils.rightPad(Integer.toHexString(48), 2, '0'));
        //充电流水号
        String tradeNo = dto.getTradeNo();
        payload.append(StringUtils.rightPad(CommonUtil.toHexString(tradeNo), 64, '0'));
        String replyMsg = ZDObjectUtil.splicingMessage(payload.toString(), gun.getPileNo(), BizConstant.Cmd.CMD_101);
        log.info("CMD=101 下发 启动充电成功:" + replyMsg);
        ByteBuf buf = Unpooled.buffer(replyMsg.getBytes().length);
        buf.writeBytes(CommonUtil.hexToByteArray(replyMsg));
        ChannelFuture future = client.writeAndFlush(buf);
    }
}
